import pandas as pd
import numpy as np
from datetime import datetime, timedelta
from vnpy.trader.object import BarData, HistoryRequest
from vnpy.trader.constant import Exchange, Interval
from vnpy.trader.database import BaseDatabase
from pathlib import Path
from typing import List, Optional
from abc import ABC, abstractmethod
from datetime import datetime
from types import ModuleType
from dataclasses import dataclass
from importlib import import_module

from vnpy.trader.object import BarData, TickData

@dataclass
class BarOverview:
    """
    Overview of bar data stored in database.
    """

    symbol: str = ""
    exchange: Exchange | None = None
    interval: Interval | None = None
    count: int = 0
    start: datetime | None = None
    end: datetime | None = None


@dataclass
class TickOverview:
    """
    Overview of tick data stored in database.
    """

    symbol: str = ""
    exchange: Exchange | None = None
    count: int = 0
    start: datetime | None = None
    end: datetime | None = None



class CsvDataAdapter(BaseDatabase):
    """CSV数据适配器"""
    
    def __init__(self, data_path: str):
        self.data_path = Path(data_path)
        self.data_cache = {}
    
    def load_bar_data(
        self,
        symbol: str,
        exchange: Exchange,
        interval: Interval,
        start: datetime,
        end: datetime
    ) -> List[BarData]:
        """
        从CSV文件加载K线数据
        """
        # 构建文件路径
        
        file_symbol = symbol.split('.')[0]
        file_path = self.data_path / f"{file_symbol}.csv"
       
        # 检查缓存
        cache_key = f"{symbol}_{interval}"
        if cache_key in self.data_cache:
            df = self.data_cache[cache_key]
        else:
            # 读取CSV文件
            if not file_path.exists():
                print(f"文件不存在: {file_path}")
                return []
            
            try:
                df = pd.read_csv(file_path)
                # 标准化列名（根据你的CSV文件格式调整）
                df.columns = df.columns.str.strip().str.lower()
                
                # 转换日期列
                if 'date' in df.columns:
                    df['datetime'] = pd.to_datetime(df['date'])
                elif 'datetime' in df.columns:
                    df['datetime'] = pd.to_datetime(df['datetime'])
                else:
                    print(f"未找到日期列: {file_path}")
                    return []
                
                # 设置索引
                df.set_index('datetime', inplace=True)
                
                # 缓存数据
                self.data_cache[cache_key] = df
                
            except Exception as e:
                print(f"读取文件失败 {file_path}: {e}")
                return []
        
        # 过滤时间范围
        mask = (df.index >= start) & (df.index <= end)
        filtered_df = df.loc[mask]
        
        # 转换为BarData列表
        bars = []
        for idx, row in filtered_df.iterrows():
            bar = BarData(
                symbol=symbol,
                exchange=exchange,
                datetime=idx.to_pydatetime(),
                interval=interval,
                volume=row.get('volume', 0),
                turnover=row.get('turnover', 0),
                open_interest=0,
                open_price=row.get('open', 0),
                high_price=row.get('high', 0),
                low_price=row.get('low', 0),
                close_price=row.get('close', 0),
                gateway_name="CSV"
            )
            bars.append(bar)
        
        return bars

    def load_bar_data_df(
        self,
        symbol: str,
        start: datetime,
        end: datetime
    ) -> pd.DataFrame:
        """
        直接返回DataFrame格式的数据（更方便处理）
        """
        bars = self.load_bar_data(symbol, Exchange.SSE, Interval.DAILY, start, end)
        
        data = []
        for bar in bars:
            data.append({
                'datetime': bar.datetime,
                'open': bar.open_price,
                'high': bar.high_price,
                'low': bar.low_price,
                'close': bar.close_price,
                'volume': bar.volume,
                'turnover': bar.turnover
            })
        
        return pd.DataFrame(data).set_index('datetime')

    
   
    def save_bar_data(self, bars: list[BarData], stream: bool = False) -> bool:
        """
        Save bar data into database.
        """
        pass

   
    def save_tick_data(self, ticks: list[TickData], stream: bool = False) -> bool:
        """
        Save tick data into database.
        """
        pass

    
  
    def load_tick_data(
        self,
        symbol: str,
        exchange: Exchange,
        start: datetime,
        end: datetime
    ) -> list[TickData]:
        """
        Load tick data from database.
        """
        pass

   
    def delete_bar_data(
        self,
        symbol: str,
        exchange: Exchange,
        interval: Interval
    ) -> int:
        """
        Delete all bar data with given symbol + exchange + interval.
        """
        pass

    
    def delete_tick_data(
        self,
        symbol: str,
        exchange: Exchange
    ) -> int:
        """
        Delete all tick data with given symbol + exchange.
        """
        pass

  
    def get_bar_overview(self) -> list[BarOverview]:
        """
        Return bar data avaible in database.
        """
        pass

   
    def get_tick_overview(self) -> list[TickOverview]:
        """
        Return tick data avaible in database.
        """
        pass
